#include <vector>
#include <iostream>
#include <cassert>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <functional>
#include <memory>
#include <thread>
#include <mutex>
#include <signal.h>
#include <condition_variable>
#include <sstream>

#include <sys/eventfd.h>
#include <sys/timerfd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
// 这里外部数据拷贝到内部数据主要用copy方法，这个方法就要获取被拷贝前数据的地址，数据拷贝到哪里的地址，所有内部buffer要提供当前的写，读实际地址

#define MUDUO_BUFFER 40960

#define INF 0
#define DBG 1
#define ERR 2
#define LOG_LEVEL DBG
static int log = 0;

#define LOG(level, format, ...)                                                                                                  \
    do                                                                                                                           \
    {                                                                                                                            \
        if (level < LOG_LEVEL)                                                                                                   \
            break;                                                                                                               \
        time_t t = time(NULL);                                                                                                   \
        struct tm *ltm = localtime(&t);                                                                                          \
        char tmp[32] = {0};                                                                                                      \
        strftime(tmp, 31, "%Y-%m-%d %H:%M:%S", ltm);                                                                             \
        log++;                                                                                                                   \
        fprintf(stdout, "[%04d %p %s %s:%d] " format "\n", log, (void *)pthread_self(), tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

// "ss: %s" -》将##__VA_ARGS__按照format "\n"格式输出     输出到输出流就是ss:字符串这种格式    格式化输出到输出流中
// 前面的一直到"n"表示格式化输出的格式
#define INF_LOG(format, ...) LOG(INF, format, ##__VA_ARGS__)
#define DBG_LOG(format, ...) LOG(DBG, format, ##__VA_ARGS__)
#define ERR_LOG(format, ...) LOG(ERR, format, ##__VA_ARGS__)
// 这个宏接受三个参数：日志级别（level）、日志格式（format）和可变参数列表（__VA_ARGS__）

namespace muduo
{
    class Buffer
    {
    public:
        Buffer() : _buffer(MUDUO_BUFFER), _readr_index(0), _writer_index(0)
        {
        }
        char *readPosition() // 当前读位置
        {
            char *pos = &(*_buffer.begin());
            return (pos + _readr_index);
        }

        char *writePosition() // 当前写位置
        {
            char *pos = &(*_buffer.begin());
            return (pos + _writer_index);
        }

        // 获取缓冲区末尾空闲空间大小--写偏移之后的空闲空间, 总体空间大小减去写偏移
        u_int64_t getBufferTailSize() { return _buffer.size() - _writer_index; }

        // 获取缓冲区起始空闲空间大小--读偏移之前的空闲空间
        u_int64_t getBufferHeadSize() { return _readr_index; }
        // 获取当前缓冲区无效数据区域
        u_int64_t getAllBufferFreeSize() { return getBufferHeadSize() + getBufferTailSize(); }

        // 获取可读数据大小 = 写偏移 - 读偏移
        u_int64_t ReadAbleSize() { return _writer_index - _readr_index; }

        // 将读偏移向后移动
        /*void MoveReadOffset(u_int64_t len)
        {
            _readr_index += len;
            return;
        }*/
        void MoveReadOffset(u_int64_t len)
        {
            if (len == 0)
                return;
            // 向后移动的大小，必须小于可读数据大小
            assert(len <= ReadAbleSize());
            _readr_index += len;
        }

        // 将写偏移向后移动
        void MoveWriteOffset(u_int64_t len)
        {
            // 这里规定如果直接MoveWriteOffset，如果len大于后置空闲空间就返回，只有在EnsureWriteSpace中才进行扩容操作
            if (len == 0)
                return;
            assert(len <= getBufferTailSize());
            _writer_index += len;
            return;
        }

        // 确保可写空间足够（整体空闲空间够了就移动数据，否则就扩容）
        void EnsureWriteSpace(u_int64_t len)
        {
            if (len <= getBufferTailSize())
                return;
            if (len <= getAllBufferFreeSize())
            {
                u_int64_t rsz = ReadAbleSize(); // 可读数据大小
                std::copy(readPosition(), readPosition() + rsz, (char *)(&*_buffer.begin()));
                _readr_index = 0;
                _writer_index = _readr_index + rsz;
            }
            else
            {
                // 此时需要扩容,库容的大小，需要为
                DBG_LOG("RESIZE %ld", len * 2 + _buffer.size());
                _buffer.resize(len * 2 + _buffer.size());
                _writer_index += len;
            }
        }
        // 数据进行写入
        void Write(const void *data, u_int64_t len)
        {
            EnsureWriteSpace(len);                                                    // 先确保数据可以写入
            std::copy((const char *)data, (const char *)data + len, writePosition()); // 将data中数据拷贝到指定的写位置
        }

        void WriteAndPush(const void *data, u_int64_t len)
        {
            Write(data, len);
            MoveWriteOffset(len);
        }

        void WriteString(const std::string &str)
        {
            Write(str.c_str(), str.size());
        }

        void WriteStringAndPush(const std::string &str)
        {
            WriteAndPush(str.c_str(), str.size());
        }

        void WriteBuffer(Buffer &buffer)
        {
            Write(buffer.readPosition(), buffer.ReadAbleSize());
        }

        void WriteBufferAndPush(Buffer &buffer)
        {
            WriteAndPush(buffer.readPosition(), buffer.ReadAbleSize());
        }

        void Read(void *buf, u_int64_t len) // const &是输入   &是输入输出   *是输出
        {
            // 将指定长度的内容读到传入的缓冲区中，读入指定len字节
            if (len == 0)
                return;
            assert(len <= ReadAbleSize());
            std::copy(readPosition(), readPosition() + len, (char *)buf); // 直接将数据拷贝到buf中
            return;
        }

        void ReadAndPop(void *buf, u_int64_t len)
        {
            Read(buf, len);
            MoveReadOffset(len);
        }

        std::string ReadAsString(u_int64_t len)
        {
            assert(len <= ReadAbleSize());
            std::string str;
            str.resize(len);
            Read((void *)str.c_str(), len);
            return str;
        }

        std::string ReadAsStringAndPop(u_int64_t len)
        {
            assert(len <= ReadAbleSize());
            std::string str;
            str.resize(len);
            ReadAndPop((void *)str.c_str(), len);
            return str;
        }

        char *FindCRLF()
        {
            // 这里"\r\n"查找到'\n'就够了
            void *pos = memchr(readPosition(), '\n', ReadAbleSize());
            if ((char *)pos == nullptr)
                return nullptr;
            return (char *)pos;
        }

        std::string GetLine()
        {
            char *pos = FindCRLF();
            if (pos == nullptr)
                return std::string("");
            return ReadAsString(pos - readPosition() + 1);
        }

        std::string GetLineAndPop()
        {
            char *pos = FindCRLF();
            if (pos == nullptr)
                return std::string("");
            return ReadAsStringAndPop(pos - readPosition() + 1);
        }

        bool ifSatisfyint32_t()
        {
            int size = ReadAbleSize();
            if (size == 32)
                return true;
            else
                return false;
        }

        void clear()
        {
            _readr_index = 0;
            _writer_index = 0;
        }

        ~Buffer() {}

    private:
        std::vector<char> _buffer;
        u_int64_t _readr_index;  // 还未读取的第一个有效位置
        u_int64_t _writer_index; // 当前写入位置，有效数据是前一个
    };

#define MAX_LISTEN 1024

    /// 这个模型是用来提供套接字以及套接字对应的操作的
    class Socket
    {
    public:
        Socket() : _sockfd(1)
        {
        }
        Socket(int sockfd) : _sockfd(sockfd)
        {
        }
        int Fd() { return _sockfd; }
        // 创建套接字
        bool Create()
        {
            // int socket(int domain, int type, int protocol)
            _sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
            if (_sockfd < 0)
            {
                DBG_LOG("SOCKET ERROR");
                return false;
            }
            return true;
        }
        // 绑定地址信息
        bool Bind(const std::string &ip, u_int16_t port)
        {
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(addr);

            int ret = ::bind(_sockfd, (sockaddr *)(&addr), len);
            if (ret < 0)
            {
                DBG_LOG("BIND ERROR");
                return false;
            }
            return true;
        }
        // 开始监听
        bool Listen(int backlog = MAX_LISTEN)
        {
            // int listen(int backlog)
            int ret = ::listen(_sockfd, MAX_LISTEN);
            if (ret < 0)
            {
                DBG_LOG("LISTEN ERROR");
                return false;
            }
            return true;
        }
        // 向服务器发起连接
        bool Connect(const std::string &ip, u_int16_t port)
        {
            struct sockaddr_in addr;
            addr.sin_family = AF_INET;
            addr.sin_port = htons(port);
            addr.sin_addr.s_addr = inet_addr(ip.c_str());
            socklen_t len = sizeof(struct sockaddr_in);
            // int connect(int sockfd, struct sockaddr*addr, socklen_t len);
            DBG_LOG("sockfd: %d", _sockfd);
            int ret = connect(_sockfd, (struct sockaddr *)&addr, len);
            if (ret < 0)
            {
                ERR_LOG("CONNECT: %d", ret);
                ERR_LOG("CONNECT SERVER FAILED!");
                return false;
            }
            return true;
        }
        // 获取新连接
        int Accept()
        {
            // int accept(int sockfd, struct sockaddr *addr, socklen_t *len);
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);

            int sockfd = ::accept(_sockfd, (sockaddr *)(&addr), &len);
            if (sockfd < 0)
            {
                DBG_LOG("Accept ERROR");
                abort();
            }
            return sockfd;
        }
        // 接收数据
        ssize_t Recv(void *buf, size_t len, int flag = 0)
        {
            // ssize_t recv(int sockfd, void *buf, size_t len, int flag);
            ssize_t ret = ::recv(_sockfd, buf, len, flag);
            DBG_LOG("ret: %ld", ret);
            if (ret <= 0)
            {
                DBG_LOG("ret: %ld", ret);
                if (errno == EINTR || errno == EWOULDBLOCK)
                {
                    return 0;
                }
                else
                {
                    ERR_LOG("RECV FAILED");
                    return -1;
                }
            }
            return ret;
        }
        ssize_t NonBlockRecv(void *buf, size_t len) // 进行非阻塞式读取
        {
            return Recv(buf, len, MSG_DONTWAIT); // MSG_DONTWAIT表示非阻塞
        }
        // 发送数据
        ssize_t Send(const void *buf, size_t len, int flag = 0)
        {
            // ssize_t send(int sockfd, void *data, size_t len, int flag);
            ssize_t ret = send(_sockfd, buf, len, flag);
            DBG_LOG("send ret %ld",ret);
            if (ret < 0)
            {
                if (errno == EAGAIN || errno == EINTR)
                {
                    return 0;
                }
                ERR_LOG("SOCKET SEND FAILED!!");
                return -1;
            }
            return ret; // 实际发送的数据长度
        }
        ssize_t NonBlockSend(void *buf, size_t len)
        {
            return Send(buf, len, MSG_DONTWAIT);
        }
        // 关闭套接字
        void Close()
        {
            if (_sockfd != -1) {
                close(_sockfd);
                _sockfd = -1;
            }
        }
        // 创建一个服务端连接  服务端直接调用这个创建一个监听套接字用来进行通信
        bool CreateServer(u_int16_t port, const std::string &ip = "0.0.0.0", bool block_flag = false)
        {
            // 1. 创建套接字，2. 绑定地址，3. 开始监听，4. 设置非阻塞， 5. 启动地址重用
            if (!Create())
                return false;
            if (!Bind(ip, port))
                return false;
            if (!Listen())
                return false;
            if (block_flag)
                NonBlock();
            ReuseAddress();
            return true;
        }
        // 创建一个客户端连接  客户端直接调用这个创建一个普通网络套接字用来进行通信
        bool CreateClient(u_int16_t port, const std::string &ip)
        {
            // 1. 创建套接字，2.指向连接服务器
            if (!Create())
                return false;
            if (!Connect(ip, port))
                return false;
            return true;
        }
        // 设置套接字选项---开启地址端口重用
        void ReuseAddress()
        {
            // int setsockopt(int fd, int leve, int optname, void *val, int vallen)
            int val = 1;
            setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(int));
            val = 1;
            setsockopt(_sockfd, SOL_SOCKET, SO_REUSEPORT, (void *)&val, sizeof(int));
        }
        // 设置套接字阻塞属性-- 设置为非阻塞
        void NonBlock()
        {
            // int fcntl(int fd, int cmd, ... /* arg */ );
            int fc = ::fcntl(_sockfd, F_GETFD);
            fc |= O_NONBLOCK;
            ::fcntl(_sockfd, F_SETFD, fc);
        }
        ~Socket()
        {
            if (_sockfd != -1)
                Close();
        }

    private:
        int _sockfd;
    };

    // 这是一个进行事件监控管理的模块
    class EventLoop;
    class Channel
    {
        using EventCallback = std::function<void()>; // 事件回调函数类型
    public:
        Channel(EventLoop *loop, int sockfd) : _loop(loop), _sockfd(sockfd), _events(0), _revents(0) {}

        int Fd() { return _sockfd; }

        u_int32_t Events() { return _events; }

        bool AbleRead() { return _events & EPOLLIN; }
        bool AbleWrite() { return _events & EPOLLOUT; }

        /// EventPool进行一次监控，触发的事件
        void setRevents(u_int32_t revents)
        {
            _revents = revents;
        }
        /// 开启读监控
        void enAbleread()
        {
            _events |= EPOLLIN;
            Update();
            return;
        }
        /// 开启写监控
        void enAblewrite()
        {
            _events |= EPOLLOUT;
            Update();
            return;
        }
        /// 关闭读监控
        void disAbleread()
        {
            _events &= ~EPOLLIN;
            Update();
            return;
        }
        /// 关闭写监控
        void disAblewrite()
        {
            _events &= ~EPOLLOUT;
            Update();
            return;
        }

        /// @brief 关闭所有事件监控
        void removeAllevents()
        {
            _events = 0;
            Update();
            return;
        }

        void Remove();
        void Update();

        void set_read_callback(const EventCallback &cb) { _read_callback = cb; }
        void set_write_callback(const EventCallback &cb) { _write_callback = cb; }
        void set_error_callback(const EventCallback &cb) { _error_callback = cb; }
        void set_close_callback(const EventCallback &cb) { _close_callback = cb; }
        void set_event_callback(const EventCallback &cb) { _event_callback = cb; }

        
        // 事件处理，一旦连接触发了事件，就调用这个函数，自己触发了什么事件如何处理自己决定
        void HandleEvent()
        {
            if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
            {
                //不管任何事件，都调用的回调函数
                if (_read_callback)
                    _read_callback();
            }
            //有可能会释放连接的操作事件，一次只处理一个
            if (_revents & EPOLLOUT)
            {
                if (_write_callback)
                    _write_callback();
            }
            else if (_revents & EPOLLERR)
            {
                if (_error_callback)
                    _error_callback(); // 一旦出错，就会释放连接，因此要放到前边调用任意回调
            }
            else if (_revents & EPOLLHUP)
            {
                if (_close_callback)
                    _close_callback();
            }
            /// 任何事件都调用该接口_event_callback
            if (_event_callback)
                _event_callback();
        }
        ~Channel()
        {
        }

    private:
        EventLoop *_loop;   // Channel对应的EventLoop
        int _sockfd;        // Channel对应的sockfd
        u_int32_t _events;  // 进行监控的事件
        u_int32_t _revents; // 本次监控触发的事件

        EventCallback _read_callback;  // 可读事件被触发的回调函数
        EventCallback _write_callback; // 可写事件被触发的回调函数
        EventCallback _error_callback; // 错误事件被触发的回调函数
        EventCallback _close_callback; // 连接断开事件被触发的回调函数
        EventCallback _event_callback; // 任意事件被触发的回调函数
    };
// 这是一个监控模块，对文件描述符进行事件监控
#define MAX_EPOLLEVENTS 1024
    class Poller
    {
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map<int, Channel *> _channels;

    private:
        // 对epoll的直接操作
        void Update(Channel *channel, int op)
        {
            // int epoll_ctl(int epfd, int op,  int fd,  struct epoll_event *ev);
            int fd = channel->Fd();
            struct epoll_event ev;
            ev.data.fd = fd;
            ev.events = channel->Events();
            int ret = epoll_ctl(_epfd, op, fd, &ev);
            if (ret < 0)
            {
                ERR_LOG("EPOLLCTL FAILED!");
            }
            return;
        }
        // 判断一个Channel是否已经添加了事件监控
        bool HasChannel(Channel *channel)
        {
            auto it = _channels.find(channel->Fd());
            if (it == _channels.end())
            {
                return false;
            }
            return true;
        }

    public:
        Poller()
        {
            _epfd = epoll_create(MAX_EPOLLEVENTS);
            if (_epfd < 0)
            {
                ERR_LOG("EPOLL CREATE FAILED!!");
                abort(); // 退出程序
            }
        }
        // 添加或修改监控事件
        void UpdateEvent(Channel *channel)
        {
            bool ret = HasChannel(channel);
            if (ret == false)
            {
                // 不存在则添加
                _channels.insert(std::make_pair(channel->Fd(), channel));
                return Update(channel, EPOLL_CTL_ADD);
            }
            return Update(channel, EPOLL_CTL_MOD);
        }
        // 移除监控
        void RemoveEvent(Channel *channel)
        {
            auto it = _channels.find(channel->Fd());
            if (it != _channels.end())
            {
                _channels.erase(it);
            }
            Update(channel, EPOLL_CTL_DEL);
        }
        // 开始监控，返回活跃连接
        void Poll(std::vector<Channel *> *active)
        {
            // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout)
            int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1);
            if (nfds < 0)
            {
                if (errno == EINTR)
                {
                    return;
                }
                ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
                abort(); // 退出程序
            }
            for (int i = 0; i < nfds; i++)
            {
                auto it = _channels.find(_evs[i].data.fd);
                assert(it != _channels.end());
                it->second->setRevents(_evs[i].events); // 设置实际就绪的事件
                active->push_back(it->second);
            }
            return;
        }
    };

    using TaskFunc = std::function<void()>;
    using ReleaseFunc = std::function<void()>;
    class TimerTask
    {
    private:
        uint64_t _id;         // 定时器任务对象ID
        uint32_t _timeout;    // 定时任务的超时时间
        TaskFunc _task_cb;    // 定时器对象要执行的定时任务
        bool _canceled;       // false-表示没有被取消， true-表示被取消
        ReleaseFunc _release; // 用于删除TimerWheel中保存的定时器对象信息
    public:
        TimerTask(uint64_t id, uint32_t delay, const TaskFunc &cb) : _id(id), _timeout(delay), _task_cb(cb), _canceled(false) {}
        ~TimerTask()
        {
            if (_canceled == false)
                _task_cb(); // 用来取消定时任务，定时器中shared_ptr<TimerTask>副本，
            _release();     // 只有最后一个shared_ptr<TimerTask>对象析构时，才会调用~TimerTask()
        } // 从而执行_task_cb()，但是前提是定时任务没有被取消，如果取消了，则不会执行定时任务
        void Cancel() { _canceled = true; }
        void SetRelease(const ReleaseFunc &cb) { _release = cb; }
        uint32_t DelayTime() { return _timeout; }
    };

    class TimerWheel
    {
    private:
        /// @brief         TimerWheel(EventLoop *loop) : _capacity(60), _tick(0), _wheel(_capacity), _loop(loop),
        /// _timerfd(CreateTimerfd()), _timer_channel(new Channel(_loop, _timerfd))
        using WeakTask = std::weak_ptr<TimerTask>;
        using PtrTask = std::shared_ptr<TimerTask>;
        int _capacity; // 表盘最大数量---其实就是最大延迟时间
        int _tick;     // 当前的秒针，走到哪里释放哪里，释放哪里，就相当于执行哪里的任务
        std::vector<std::vector<PtrTask>> _wheel;
        std::unordered_map<uint64_t, WeakTask> _timers;

        EventLoop *_loop;
        int _timerfd; // 定时器描述符--可读事件回调就是读取计数器，执行定时任务
        std::unique_ptr<Channel> _timer_channel;

    private:
        void RemoveTimer(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it != _timers.end())
            {
                _timers.erase(it);
            }
        }
        static int CreateTimerfd()
        {
            int timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
            if (timerfd < 0)
            {
                ERR_LOG("TIMERFD CREATE FAILED!");
                abort();
            }
            // int timerfd_settime(int fd, int flags, struct itimerspec *new, struct itimerspec *old);
            struct itimerspec itime;
            itime.it_value.tv_sec = 1;
            itime.it_value.tv_nsec = 0; // 第一次超时时间为1s后
            itime.it_interval.tv_sec = 1;
            itime.it_interval.tv_nsec = 0; // 第一次超时后，每次超时的间隔时
            timerfd_settime(timerfd, 0, &itime, NULL);
            return timerfd;
        }
        int ReadTimefd()
        {
            uint64_t times;
            // 有可能因为其他描述符的事件处理花费事件比较长，然后在处理定时器描述符事件的时候，有可能就已经超时了很多次
            // read读取到的数据times就是从上一次read之后超时的次数
            int ret = read(_timerfd, &times, 8);
            if (ret < 0)
            {
                ERR_LOG("READ TIMEFD FAILED!");
                abort();
            }
            return times;
        }
        // 这个函数应该每秒钟被执行一次，相当于秒针向后走了一步
        void RunTimerTask()
        {
            _tick = (_tick + 1) % _capacity;
            _wheel[_tick].clear(); // 清空指定位置的数组，就会把数组中保存的所有管理定时器对象的shared_ptr释放掉
        }
        void OnTime()
        {
            // 根据实际超时的次数，执行对应的超时任务
            int times = ReadTimefd();
            for (int i = 0; i < times; i++)
            {
                RunTimerTask();
            }
        }
        void TimerAddInLoop(uint64_t id, uint32_t delay, const TaskFunc &cb)
        {
            PtrTask pt(new TimerTask(id, delay, cb));
            pt->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, id));
            int pos = (_tick + delay) % _capacity;
            _wheel[pos].push_back(pt);
            _timers[id] = WeakTask(pt);
        }
        void TimerRefreshInLoop(uint64_t id)
        {
            // 通过保存的定时器对象的weak_ptr构造一个shared_ptr出来，添加到轮子中
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return; // 没找着定时任务，没法刷新，没法延迟
            }
            PtrTask pt = it->second.lock(); // lock获取weak_ptr管理的对象对应的shared_ptr
            int delay = pt->DelayTime();
            int pos = (_tick + delay) % _capacity;
            _wheel[pos].push_back(pt);
        }
        void TimerCancelInLoop(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return; // 没找着定时任务，没法刷新，没法延迟
            }
            PtrTask pt = it->second.lock();
            if (pt)
                pt->Cancel();
        }

    public:
        TimerWheel(EventLoop *loop) : _capacity(60), _tick(0), _wheel(_capacity), _loop(loop),
                                      _timerfd(CreateTimerfd()), _timer_channel(new Channel(_loop, _timerfd))
        {
            _timer_channel->set_read_callback(std::bind(&TimerWheel::OnTime, this));
            _timer_channel->enAbleread(); // 启动读事件监控
        }
        /*定时器中有个_timers成员，定时器信息的操作有可能在多线程中进行，因此需要考虑线程安全问题*/
        /*如果不想加锁，那就把对定期的所有操作，都放到一个线程中进行*/
        void TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb);
        // 刷新/延迟定时任务
        void TimerRefresh(uint64_t id);
        void TimerCancel(uint64_t id);
        /*这个接口存在线程安全问题--这个接口实际上不能被外界使用者调用，只能在模块内，在对应的EventLoop线程内执行*/
        bool HasTimer(uint64_t id)
        {
            auto it = _timers.find(id);
            if (it == _timers.end())
            {
                return false;
            }
            return true;
        }
    };

    class EventLoop
    {
    public:
        /// @brief 初始化列表会按照成员变量在类中声明的顺序进行初始化
        using Funtor = std::function<void()>;
        EventLoop() :_thread_id(std::this_thread::get_id()), 
        _eventfd(CreateEventFd()), 
        _eventfd_channel(new Channel(this, _eventfd)),
        _timerWheel(this)
        {
            /// 读就绪就去把数据读出来，防止后续数据一直在eventfd中，一直调用eventfd的读就绪事件
            /// 为什么一直循环，因为QueueInLoop是weakupeventfd然后往eventfd中写入数据，结果读就绪事件设置成了
            /// EventLoop::weakupeventfd,就会导致事件一直就绪一直循环weakupeventfd
            /// 一开始没有出现问题的原因是: RunInLoop中忘记调用weakupeventfd，但是一直有事件就绪
            _eventfd_channel->set_read_callback(std::bind(&EventLoop::ReadEventfd, this));
            _eventfd_channel->enAbleread();
        }
        //三步走--事件监控-》就绪事件处理-》执行任务
        void Start() {
            while(1) {
                //1. 事件监控， 
                std::vector<Channel *> actives;
                _poller.Poll(&actives);
                //2. 事件处理。 
                for (auto &channel : actives) {
                    channel->HandleEvent();
                }
                //3. 执行任务
                RunAllTask();
            }
        }
        void RunAllTask()
        {
            std::vector<Funtor> func;
            {
                std::unique_lock<std::mutex> _lock(_mutex);
                func.swap(_tasks);
            }
            for (auto fuc : func)
            {
                fuc();
            }
            return;
        }
        /// @brief 移除事件监控
        /// @param channel
        void RemoveEvent(Channel *channel) { _poller.RemoveEvent(channel); }
        /// @brief 更新事件监控
        /// @param channel
        void UpdateEvent(Channel *channel) { _poller.UpdateEvent(channel); }
        bool isInloop() {return (_thread_id == std::this_thread::get_id()); }
        void AssertInLoop() { assert(_thread_id == std::this_thread::get_id()); }

        void RunInLoop(const Funtor &cb)
        {
            ///DBG_LOG("void RunInLoop(const Funtor &cb)");
            /// 如果是EventLoop对应的线程,直接执行
            if (isInloop()){cb();}
            /// 不执行两次这个操作，上次执行两次是因为remove是QueueInLoop就导致
            else{QueueInLoop(cb);}
        }

        void QueueInLoop(const Funtor &cb)
        {
            /// 因为连接有对应的loop，那么就是连接把Functor(对连接的一些操作压入到队列中了)
            //DBG_LOG("void QueueInLoop(const Funtor &cb)");
            {
                std::unique_lock<std::mutex> _lock(_mutex);
                _tasks.push_back(cb);
            }
            //唤醒有可能因为没有事件就绪，而导致的epoll阻塞；
            //其实就是给eventfd写入一个数据，eventfd就会触发可读事件
            WeakUpEventFd();
        }
        /// @brief 不属于任何一个类对象，初始化对象的时候可以调用
        /// @return
        static int CreateEventFd()
        {
            int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
            if (efd < 0)
            {
                ERR_LOG("CREATE EVENTFD FAILED!!");
                abort(); // 让程序异常退出
            }
            return efd;
        }

        void ReadEventfd() {
            uint64_t res = 0;
            int ret = read(_eventfd, &res, sizeof(res));
            if (ret < 0) {
                //EINTR -- 被信号打断；   EAGAIN -- 表示无数据可读
                if (errno == EINTR || errno == EAGAIN) {
                    return;
                }
                ERR_LOG("READ EVENTFD FAILED!");
                abort();
            }
            return ;
        }
        void WeakUpEventFd() {
            //DBG_LOG("void WeakUpEventFd()");
            uint64_t val = 1;
            int ret = write(_eventfd, &val, sizeof(val));
            if (ret < 0) {
                if (errno == EINTR) {
                    return;
                }
                ERR_LOG("READ EVENTFD FAILED!");
                abort();
            }
            return ;
        }

        void TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb) { return _timerWheel.TimerAdd(id, delay, cb); }
        void TimerRefresh(uint64_t id) { return _timerWheel.TimerRefresh(id); }
        void TimerCancel(uint64_t id) { return _timerWheel.TimerCancel(id); }
        bool HasTimer(uint64_t id) { return _timerWheel.HasTimer(id); }

    private:
        std::thread::id _thread_id; // 线程ID,验证当前线程是否是该连接对应的EventLoop线程
        Poller _poller;             // 事件监控模块
        int _eventfd;               // eventfd用来通知
        std::unique_ptr<Channel> _eventfd_channel;
        std::vector<Funtor> _tasks;
        TimerWheel _timerWheel; // 定时器模块
        std::mutex _mutex;      // 任务队列的锁
    };

    class LoopThread {
        private:
            /*用于实现_loop获取的同步关系，避免线程创建了，但是_loop还没有实例化之前去获取_loop*/
            std::mutex _mutex;          // 互斥锁
            std::condition_variable _cond;   // 条件变量
            EventLoop *_loop;       // EventLoop指针变量，这个对象需要在线程内实例化
            std::thread _thread;    // EventLoop对应的线程,应该就是pthread_create创建的线程返回的起始地址
        private:
            /*实例化 EventLoop 对象，唤醒_cond上有可能阻塞的线程，并且开始运行EventLoop模块的功能*/
            void ThreadEntry() {
                EventLoop loop;
                {
                    std::unique_lock<std::mutex> lock(_mutex);//加锁
                    _loop = &loop;
                    _cond.notify_all();
                }
                loop.Start();
            }
        public:
            /*创建线程，设定线程入口函数*/
            LoopThread():_loop(NULL), _thread(std::thread(&LoopThread::ThreadEntry, this)) {}
            /*返回当前线程关联的EventLoop对象指针*/
            EventLoop *GetLoop() {
                EventLoop *loop = NULL;
                {
                    std::unique_lock<std::mutex> lock(_mutex);//加锁
                    _cond.wait(lock, [&](){ return _loop != NULL; });//loop为NULL就一直阻塞
                    loop = _loop;
                }
                return loop;
            }
    };
    
    class LoopThreadPool {
        private:
            int _thread_count;
            int _next_idx;
            EventLoop *_baseloop;
            std::vector<LoopThread*> _threads; //通过管理_threads达到管理事件循环模块的目的
            std::vector<EventLoop *> _loops;
        public:
            LoopThreadPool(EventLoop *baseloop):_thread_count(0), _next_idx(0), _baseloop(baseloop) {}
            void SetThreadCount(int count) { _thread_count = count; }
            void Create() {
                if (_thread_count > 0) {
                    _threads.resize(_thread_count);
                    _loops.resize(_thread_count);
                    for (int i = 0; i < _thread_count; i++) {
                        _threads[i] = new LoopThread();
                        _loops[i] = _threads[i]->GetLoop();
                    }
                }
                return ;
            }
            EventLoop *NextLoop() {
                if (_thread_count == 0) {
                    return _baseloop;
                }
                _next_idx = (_next_idx + 1) % _thread_count;
                return _loops[_next_idx];
            }
    };
    class Any{
        private:
            class holder {
                public:
                    virtual ~holder() {}
                    virtual const std::type_info& type() = 0;
                    virtual holder *clone() = 0;
            };
            template<class T>
            class placeholder: public holder {
                public:
                    placeholder(const T &val): _val(val) {}
                    // 获取子类对象保存的数据类型
                    virtual const std::type_info& type() { return typeid(T); }
                    // 针对当前的对象自身，克隆出一个新的子类对象
                    virtual holder *clone() { return new placeholder(_val); }
                public:
                    T _val;
            };
            holder *_content;
        public:
            Any():_content(NULL) {}
            template<class T>
            Any(const T &val):_content(new placeholder<T>(val)) {}
            Any(const Any &other):_content(other._content ? other._content->clone() : NULL) {}
            ~Any() { delete _content; }
    
            Any &swap(Any &other) {
                std::swap(_content, other._content);
                return *this;
            }
    
// 返回子类对象保存的数据的指Any调用的是get<HttpContext>(),那么你就必须保证我Any中的_content指向的placeholder保存的数据类型是HttpContext
// void SetContext(const Any &context) { _context = context; }  conn->SetContext(HttpContext()); 
// SetContext(HttpContext());调用Any(const T &val):_content(new placeholder<T>(val)) {}  构造一个Any，内部指针指向placeholder<HttpContext>
// 此时_content holder指向的数据类型是placeholder<HttpContext>
// 此时HttpContext *context = conn->GetContext()->get<HttpContext>();就能满足调用的函数参数类型和_content内部指针指向的placeholder保存的数据类型一致
            template<class T>
            T *get() {
                //想要获取的数据类型，必须和保存的数据类型一致
                //std::cout << typeid(T).name() << std::endl;      // 打印 T 的（编译器修饰）名字
                //std::cout << _content->type().name() << std::endl;
                assert(typeid(T) == _content->type());
                return &((placeholder<T>*)_content)->_val;
            }
            //赋值运算符的重载函数
            template<class T>
            Any& operator=(const T &val) {
                //为val构造一个临时的通用容器，然后与当前容器自身进行指针交换，临时对象释放的时候，原先保存的数据也就被释放
                Any(val).swap(*this);
                return *this;
            }
            Any& operator=(const Any &other) {
                Any(other).swap(*this);
                return *this;
            }
    };

    class Connection;
    //DISCONECTED -- 连接关闭状态；   CONNECTING -- 连接建立成功-待处理状态
    //CONNECTED -- 连接建立完成，各种设置已完成，可以通信的状态；  DISCONNECTING -- 待关闭状态
    typedef enum { DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING}ConnStatu;
    using PtrConnection = std::shared_ptr<Connection>;
    class Connection : public std::enable_shared_from_this<Connection> {
        private:
            uint64_t _conn_id;  // 连接的唯一ID，便于连接的管理和查找
            //uint64_t _timer_id;   //定时器ID，必须是唯一的，这块为了简化操作使用conn_id作为定时器ID
            int _sockfd;        // 连接关联的文件描述符
            bool _enable_inactive_release;  // 连接是否启动非活跃销毁的判断标志，默认为false
            EventLoop *_loop;   // 连接所关联的一个EventLoop
            ConnStatu _statu;   // 连接状态
            Socket _socket;     // 套接字操作管理
            Channel _channel;   // 连接的事件管理
            Buffer _in_buffer;  // 输入缓冲区---存放从socket中读取到的数据
            Buffer _out_buffer; // 输出缓冲区---存放要发送给对端的数据
            Any _context;       // 请求的接收处理上下文

            /*这四个回调函数，是让服务器模块来设置的（其实服务器模块的处理回调也是组件使用者设置的）*/
            /*换句话说，这几个回调都是组件使用者使用的*/
            using ConnectedCallback = std::function<void(const PtrConnection&)>;
            using MessageCallback = std::function<void(const PtrConnection&, Buffer *)>;
            using ClosedCallback = std::function<void(const PtrConnection&)>;
            using AnyEventCallback = std::function<void(const PtrConnection&)>;
            ConnectedCallback _connected_callback;
            MessageCallback _message_callback;
            ClosedCallback _closed_callback;
            AnyEventCallback _event_callback;
            /*组件内的连接关闭回调--组件内设置的，因为服务器组件内会把所有的连接管理起来，一旦某个连接要关闭*/
            /*就应该从管理的地方移除掉自己的信息*/
            ClosedCallback _server_closed_callback;
        private:
            /*五个channel的事件回调函数*/
            //描述符可读事件触发后调用的函数，接收socket数据放到接收缓冲区中，然后调用_message_callback
            void HandleRead() {
                //1. 接收socket的数据，放到缓冲区
                char buf[65536];
                ssize_t ret = _socket.NonBlockRecv(buf, 65535);
                if (ret < 0) {
                    //出错了,不能直接关闭连接
                    return ShutdownInLoop();
                }
                //这里的等于0表示的是没有读取到数据，而并不是连接断开了，连接断开返回的是-1
                //将数据放入输入缓冲区,写入之后顺便将写偏移向后移动
                _in_buffer.WriteAndPush(buf, ret);
                //2. 调用message_callback进行业务处理
                if (_in_buffer.ReadAbleSize() > 0) {
                    //shared_from_this--从当前对象自身获取自身的shared_ptr管理对象
                    DBG_LOG("_in_buffer.ReadAbleSize(),%ld",_in_buffer.ReadAbleSize());
                    DBG_LOG("_in_buffer.readPosition(),%s",_in_buffer.readPosition());
                    return _message_callback(shared_from_this(), &_in_buffer);
                }
            }
            //描述符可写事件触发后调用的函数，将发送缓冲区中的数据进行发送
            void HandleWrite() {
                //_out_buffer中保存的数据就是要发送的数据
                DBG_LOG("_out_buffer.readPosition(),%s",_out_buffer.readPosition());
                DBG_LOG("_out_buffer.ReadAbleSize(),%ld",_out_buffer.ReadAbleSize());
                ssize_t ret = _socket.NonBlockSend(_out_buffer.readPosition(), _out_buffer.ReadAbleSize());
                if (ret < 0) {
                    //发送错误就该关闭连接了，
                    if (_in_buffer.ReadAbleSize() > 0) {
                        _message_callback(shared_from_this(), &_in_buffer);
                    }
                    return Release();//这时候就是实际的关闭释放操作了。
                }
                _out_buffer.MoveReadOffset(ret);//千万不要忘了，将读偏移向后移动
                if (_out_buffer.ReadAbleSize() == 0) {
                    _channel.disAblewrite();// 没有数据待发送了，关闭写事件监控
                    //如果当前是连接待关闭状态，则有数据，发送完数据释放连接，没有数据则直接释放
                    if (_statu == DISCONNECTING) {
                        return Release();
                    }
                }
                return;
            }
            //描述符触发挂断事件
            void HandleClose() {
                /*一旦连接挂断了，套接字就什么都干不了了，因此有数据待处理就处理一下，完毕关闭连接*/
                if (_in_buffer.ReadAbleSize() > 0) {
                    _message_callback(shared_from_this(), &_in_buffer);
                }
                return Release();
            }
            //描述符触发出错事件
            void HandleError() {
                return HandleClose();
            }
            //描述符触发任意事件: 1. 刷新连接的活跃度--延迟定时销毁任务；  2. 调用组件使用者的任意事件回调
            void HandleEvent() {
                if (_enable_inactive_release == true)  {  _loop->TimerRefresh(_conn_id); }
                if (_event_callback)  {  _event_callback(shared_from_this()); }
            }
            //连接获取之后，所处的状态下要进行各种设置（启动读监控,调用回调函数）
            void EstablishedInLoop() {
                // 1. 修改连接状态；  2. 启动读事件监控；  3. 调用回调函数
                assert(_statu == CONNECTING);//当前的状态必须一定是上层的半连接状态
                _statu = CONNECTED;//当前函数执行完毕，则连接进入已完成连接状态
                // 一旦启动读事件监控就有可能会立即触发读事件，如果这时候启动了非活跃连接销毁
                _channel.enAbleread();
                if (_connected_callback) _connected_callback(shared_from_this());
            }
            //这个接口才是实际的释放接口
            void ReleaseInLoop() {
                if (_sockfd < 0) return;          // 已经走过一次了
                //1. 修改连接状态，将其置为DISCONNECTED
                _statu = DISCONNECTED;
                //2. 移除连接的事件监控
                _channel.Remove();
                //3. 关闭描述符
                _socket.Close();
                //4. 如果当前定时器队列中还有定时销毁任务，则取消任务
                if (_loop->HasTimer(_conn_id)) CancelInactiveReleaseInLoop();
                //5. 调用关闭回调函数，避免先移除服务器管理的连接信息导致Connection被释放，再去处理会出错，因此先调用用户的回调函数
                if (_closed_callback) _closed_callback(shared_from_this());
                //移除服务器内部管理的连接信息
                if (_server_closed_callback) _server_closed_callback(shared_from_this());
            }
            //这个接口并不是实际的发送接口，而只是把数据放到了发送缓冲区，启动了可写事件监控
            void SendInLoop(Buffer &buf) {
                //DBG_LOG("void SendInLoop(Buffer &buf)");
                if (_statu == DISCONNECTED) return ;
                _out_buffer.WriteBufferAndPush(buf);
                if (_channel.AbleWrite() == false) {
                    _channel.enAblewrite();
                }
            }
            //这个关闭操作并非实际的连接释放操作，需要判断还有没有数据待处理，待发送
            void ShutdownInLoop() {
                _statu = DISCONNECTING;// 设置连接为半关闭状态
                if (_in_buffer.ReadAbleSize() > 0) {
                    if (_message_callback) _message_callback(shared_from_this(), &_in_buffer);
                }
                //要么就是写入数据的时候出错关闭，要么就是没有待发送数据，直接关闭
                if (_out_buffer.ReadAbleSize() > 0) {
                    if (_channel.AbleWrite() == false) {
                        _channel.enAblewrite();
                    }
                }
                if (_out_buffer.ReadAbleSize() == 0) {
                    Release();
                }
            }
            //启动非活跃连接超时释放规则
            void EnableInactiveReleaseInLoop(int sec) {
                //1. 将判断标志 _enable_inactive_release 置为true
                _enable_inactive_release = true;
                //2. 如果当前定时销毁任务已经存在，那就刷新延迟一下即可
                if (_loop->HasTimer(_conn_id)) {
                    return _loop->TimerRefresh(_conn_id);
                }
                //3. 如果不存在定时销毁任务，则新增
                _loop->TimerAdd(_conn_id, sec, std::bind(&Connection::Release, this));
            }
            void CancelInactiveReleaseInLoop() 
            {
                _enable_inactive_release = false;
                if (_loop->HasTimer(_conn_id)) { _loop->TimerCancel(_conn_id);}
            }
            void UpgradeInLoop(const Any &context, 
                        const ConnectedCallback &conn, 
                        const MessageCallback &msg, 
                        const ClosedCallback &closed, 
                        const AnyEventCallback &event) {
                _context = context;
                _connected_callback = conn;
                _message_callback = msg;
                _closed_callback = closed;
                _event_callback = event;
            }
        public:
            Connection(EventLoop *loop, uint64_t conn_id, int sockfd):_conn_id(conn_id), _sockfd(sockfd),
                _enable_inactive_release(false), _loop(loop), _statu(CONNECTING), _socket(_sockfd),
                _channel(loop, _sockfd) {
                _channel.set_close_callback(std::bind(&Connection::HandleClose, this));
                _channel.set_event_callback(std::bind(&Connection::HandleEvent, this));
                _channel.set_read_callback(std::bind(&Connection::HandleRead, this));
                _channel.set_write_callback(std::bind(&Connection::HandleWrite, this));
                _channel.set_error_callback(std::bind(&Connection::HandleError, this));
            }
            ~Connection() { DBG_LOG("RELEASE CONNECTION:%p", this); }
            //获取管理的文件描述符
            int Fd() { return _sockfd; }
            //获取连接ID
            int Id() { return _conn_id; }
            //是否处于CONNECTED状态
            bool Connected() { return (_statu == CONNECTED); }
            //设置上下文--连接建立完成时进行调用
            void SetContext(const Any &context) { _context = context; }
            //获取上下文，返回的是指针
            Any *GetContext() { return &_context; }
            void SetConnectedCallback(const ConnectedCallback&cb) { _connected_callback = cb; }
            void SetMessageCallback(const MessageCallback&cb) { _message_callback = cb; }
            void SetClosedCallback(const ClosedCallback&cb) { _closed_callback = cb; }
            void SetAnyEventCallback(const AnyEventCallback&cb) { _event_callback = cb; }
            void SetSrvClosedCallback(const ClosedCallback&cb) { _server_closed_callback = cb; }
            //连接建立就绪后，进行channel回调设置，启动读监控，调用_connected_callback
            void Established() {
                //DBG_LOG("Established()");
                _loop->RunInLoop(std::bind(&Connection::EstablishedInLoop, this));
            }
            //发送数据，将数据放到发送缓冲区，启动写事件监控
            void Send(const char *data, size_t len) {
                //DBG_LOG("void Send(const char *data, size_t len)");
                //外界传入的data，可能是个临时的空间，我们现在只是把发送操作压入了任务池，有可能并没有被立即执行
                //因此有可能执行的时候，data指向的空间有可能已经被释放了。
                Buffer buf;
                buf.WriteAndPush(data, len);
                //DBG_LOG("buf->readPosition(),%s",buf.readPosition());
                //DBG_LOG("buf->ReadAbleSize(),%ld",buf.ReadAbleSize());
                _loop->RunInLoop(std::bind(&Connection::SendInLoop, this, std::move(buf)));
            }   //sockfd和一个连接对象，是一一对应的关系，一个连接对象内部有两个缓冲区
                //每个连接创建一个channel和EventPool交互从而让EventPool内部的epoll监听sockfd事件
            //提供给组件使用者的关闭接口--并不实际关闭，需要判断有没有数据待处理
            void Shutdown() {
                _loop->RunInLoop(std::bind(&Connection::ShutdownInLoop, this));
            }
            void Release() {
                _loop->QueueInLoop(std::bind(&Connection::ReleaseInLoop, this));
            }
            //启动非活跃销毁，并定义多长时间无通信就是非活跃，添加定时任务
            void EnableInactiveRelease(int sec) {
                _loop->RunInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop, this, sec));
            }
            //取消非活跃销毁
            void CancelInactiveRelease() {
                _loop->RunInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop, this));
            }
            //切换协议---重置上下文以及阶段性回调处理函数 -- 而是这个接口必须在EventLoop线程中立即执行
            //防备新的事件触发后，处理的时候，切换任务还没有被执行--会导致数据使用原协议处理了。
            void Upgrade(const Any &context, const ConnectedCallback &conn, const MessageCallback &msg, 
                        const ClosedCallback &closed, const AnyEventCallback &event) {
                _loop->AssertInLoop();
                _loop->RunInLoop(std::bind(&Connection::UpgradeInLoop, this, context, conn, msg, closed, event));
            }
    };

    class Acceptor {
        private:
            Socket _socket;//用于创建监听套接字
            EventLoop *_loop; //用于对监听套接字进行事件监控
            Channel _channel; //用于对监听套接字进行事件管理

            using AcceptCallback = std::function<void(int)>;
            AcceptCallback _accept_callback;
        private:
            /*监听套接字的读事件回调处理函数---获取新连接，调用_accept_callback函数进行新连接处理*/
            void HandleRead() {
                int newfd = _socket.Accept();
                if (newfd < 0) {
                    return ;
                }
                if (_accept_callback) _accept_callback(newfd);
            }
            int CreateServer(int port) {
                bool ret = _socket.CreateServer(port);
                assert(ret == true);
                return _socket.Fd();
            }
        public:
            /*不能将启动读事件监控，放到构造函数中，必须在设置回调函数后，再去启动*/
            /*否则有可能造成启动监控后，立即有事件，处理的时候，回调函数还没设置：新连接得不到处理，且资源泄漏*/
            Acceptor(EventLoop *loop, int port): _socket(CreateServer(port)), _loop(loop), 
                _channel(loop, _socket.Fd()) {
                _channel.set_read_callback(std::bind(&Acceptor::HandleRead, this));
            }
            void SetAcceptCallback(const AcceptCallback &cb) { _accept_callback = cb; }
            void Listen() { _channel.enAbleread(); }
    };

    class TcpServer {
        private:
            int _timeout;           //这是非活跃连接的统计时间---多长时间无通信就是非活跃连接
            uint64_t _next_id;      //这是一个自动增长的连接ID，
            int _port;
            bool _enable_inactive_release;//是否启动了非活跃连接超时销毁的判断标志
            EventLoop _baseloop;    //这是主线程的EventLoop对象，负责监听事件的处理
            Acceptor _acceptor;    //这是监听套接字的管理对象
            LoopThreadPool _pool;   //这是从属EventLoop线程池
            std::unordered_map<uint64_t, PtrConnection> _conns;//保存管理所有连接对应的shared_ptr对象

            using ConnectedCallback = std::function<void(const PtrConnection&)>;
            using MessageCallback = std::function<void(const PtrConnection&, Buffer *)>;
            using ClosedCallback = std::function<void(const PtrConnection&)>;
            using AnyEventCallback = std::function<void(const PtrConnection&)>;
            using Functor = std::function<void()>;
            ConnectedCallback _connected_callback;
            MessageCallback _message_callback;
            ClosedCallback _closed_callback;
            AnyEventCallback _event_callback;
        private:
            void RunAfterInLoop(const Functor &task, int delay) {
                _next_id++;
                _baseloop.TimerAdd(_next_id, delay, task);
            }
            //为新连接构造一个Connection进行管理
            void NewConnection(int fd) {
                //DBG_LOG("void NewConnection(int fd),%d",fd);
                _next_id++;
                PtrConnection conn(new Connection(_pool.NextLoop(), _next_id, fd));
                conn->SetMessageCallback(_message_callback);
                conn->SetClosedCallback(_closed_callback);
                conn->SetConnectedCallback(_connected_callback);
                conn->SetAnyEventCallback(_event_callback);
                conn->SetSrvClosedCallback(std::bind(&TcpServer::RemoveConnection, this, std::placeholders::_1));
                if (_enable_inactive_release) conn->EnableInactiveRelease(_timeout);//启动非活跃超时销毁
                conn->Established();//就绪初始化
                _conns.insert(std::make_pair(_next_id, conn));
            }
            void RemoveConnectionInLoop(const PtrConnection &conn) {
                //DBG_LOG("RemoveConnectionInLoop(const PtrConnection &conn)");
                int id = conn->Id();
                auto it = _conns.find(id);
                if (it != _conns.end()) {
                    _conns.erase(it);
                }
            }
            //从管理Connection的_conns中移除连接信息
            void RemoveConnection(const PtrConnection &conn) {_baseloop.RunInLoop(std::bind(&TcpServer::RemoveConnectionInLoop, this, conn));}
        public:
            TcpServer(int port):
                _timeout(0),
                _next_id(0),
                _port(port),  
                _enable_inactive_release(false), 
                _acceptor(&_baseloop, port),
                _pool(&_baseloop) 
            {
                _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
                _acceptor.Listen();//将监听套接字挂到baseloop上
            }
            void SetThreadCount(int count) { return _pool.SetThreadCount(count); }
            void SetConnectedCallback(const ConnectedCallback&cb) { _connected_callback = cb; }
            void SetMessageCallback(const MessageCallback&cb) { _message_callback = cb; }
            void SetClosedCallback(const ClosedCallback&cb) { _closed_callback = cb; }
            void SetAnyEventCallback(const AnyEventCallback&cb) { _event_callback = cb; }
            void EnableInactiveRelease(int timeout) { _timeout = timeout; _enable_inactive_release = true; }
            //用于添加一个定时任务
            void RunAfter(const Functor &task, int delay) {
                _baseloop.RunInLoop(std::bind(&TcpServer::RunAfterInLoop, this, task, delay));
            }
            void Start() { _pool.Create();  _baseloop.Start(); }
    };


    void Channel::Remove() { return _loop->RemoveEvent(this); }
    void Channel::Update() { return _loop->UpdateEvent(this); }
    void TimerWheel::TimerAdd(uint64_t id, uint32_t delay, const TaskFunc &cb) {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerAddInLoop, this, id, delay, cb));
    }
    //刷新/延迟定时任务
    void TimerWheel::TimerRefresh(uint64_t id) {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerRefreshInLoop, this, id));
    }
    void TimerWheel::TimerCancel(uint64_t id) {
        _loop->RunInLoop(std::bind(&TimerWheel::TimerCancelInLoop, this, id));
    }

    class NetWork {
        public:
            NetWork() {
                DBG_LOG("SIGPIPE INIT");
                signal(SIGPIPE, SIG_IGN);
            }
    };
    static NetWork nw;
}
